package com.youlu.campus.service.account.impl;

import com.youlu.campus.entity.*;
import com.youlu.campus.service.account.AccountMobileInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class AccountMobileInfoServiceImpl implements AccountMobileInfoService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public AccountMobileInfo find(String mobile, String userId) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("mobile").is(mobile));
        return mongoTemplate.findOne(query, AccountMobileInfo.class);
    }

    @Override
    public boolean create(@NotNull AccountMobileInfo req) {
        req.setId(null);
        req.setCreatedTime(new Date());
        req = mongoTemplate.insert(req);
        if (StringUtils.isBlank(req.getId())) {
            return false;
        }
        return true;
    }

    @Async
    @Override
    public void updateAccountMobile(String userId, String mobile, String platform) {
        log.info(":>>> 开始更新账户:{}, 平台:{} 手机号:{}", userId, mobile, platform);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(mobile) || StringUtils.isBlank(platform)) {
            log.error("开始更新账户更新手机号参数错误");
            return;
        }
        Date date = new Date();
        Query query = new Query().addCriteria(Criteria.where("id").is(userId));
        UserPO userPO = mongoTemplate.findOne(query, UserPO.class);
        if (Objects.isNull(userPO)) {
            log.error("账户不存在:{}", userId);
            return;
        }
        if (Boolean.FALSE.equals(userPO.getCheckedMobile()) || StringUtils.isBlank(userPO.getMobile())) {
            Update update = new Update();
            update.set("mobile", mobile);
            update.set("checkedMobile", true);
            update.set("checkedMobileTime", date);
            mongoTemplate.updateFirst(query, update, UserPO.class);
        }
        switch (platform) {
            case "qq":
                this.updateQQMiniUserMobile(userId, mobile, date);
                break;
            case "wechat-h5":
                this.updateWechatH5UserMobile(userId, mobile, date);
                break;
            case "qq-h5":
                this.updateQQh5UserMobile(userId, mobile, date);
                break;
            case "h5":
                this.updateH5UserMobile(userId, mobile, date);
                break;
            case "wechat-mini":
                this.updateWechatMiniMobile(userId, mobile, date);
                break;
            case "app":
                this.updateAppUserMobile(userId, mobile, date);
                break;
            case "wechat-third":
                this.updateWechatThirdMobile(userId, mobile, date);
                break;
            default:
        }

    }

    /**
     * 更新QQ小程序用户账号
     *
     * @param userId
     * @param mobile
     * @param date
     */
    private void updateQQMiniUserMobile(String userId, String mobile, Date date) {
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId));
        List<QQMiniUserPO> users = mongoTemplate.find(query, QQMiniUserPO.class);
        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        for (QQMiniUserPO userPO : users) {
            if (!Boolean.TRUE.equals(userPO.getCheckedMobile()) || StringUtils.isBlank(userPO.getMobile())) {
                updateMobileFun(userPO.getId(), mobile, date, WechatThirdUserPO.class);
            }
        }

    }

    private void updateWechatH5UserMobile(String userId, String mobile, Date date) {
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId));
        List<WechatH5UserPO> users = mongoTemplate.find(query, WechatH5UserPO.class);
        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        for (WechatH5UserPO userPO : users) {
            if (!Boolean.TRUE.equals(userPO.getCheckedMobile()) || StringUtils.isBlank(userPO.getMobile())) {
                updateMobileFun(userPO.getId(), mobile, date, WechatThirdUserPO.class);
            }
        }

    }

    private void updateQQh5UserMobile(String userId, String mobile, Date date) {
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId));
        List<QQH5UserPO> users = mongoTemplate.find(query, QQH5UserPO.class);
        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        for (QQH5UserPO userPO : users) {
            if (!Boolean.TRUE.equals(userPO.getCheckedMobile()) || StringUtils.isBlank(userPO.getMobile())) {
                updateMobileFun(userPO.getId(), mobile, date, WechatThirdUserPO.class);
            }
        }

    }

    private void updateH5UserMobile(String userId, String mobile, Date date) {
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId));
        List<H5UserPO> users = mongoTemplate.find(query, H5UserPO.class);
        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        for (H5UserPO userPO : users) {
            if (!Boolean.TRUE.equals(userPO.getCheckedMobile()) || StringUtils.isBlank(userPO.getMobile())) {
                updateMobileFun(userPO.getId(), mobile, date, WechatThirdUserPO.class);
            }
        }

    }

    private void updateWechatMiniMobile(String userId, String mobile, Date date) {
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId));
        List<WechatMiniUserPO> users = mongoTemplate.find(query, WechatMiniUserPO.class);
        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        for (WechatMiniUserPO userPO : users) {
            if (!Boolean.TRUE.equals(userPO.getCheckedMobile()) || StringUtils.isBlank(userPO.getMobile())) {
                updateMobileFun(userPO.getId(), mobile, date, WechatThirdUserPO.class);
            }
        }

    }

    private void updateAppUserMobile(String userId, String mobile, Date date) {
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId));
        List<AppUserPO> users = mongoTemplate.find(query, AppUserPO.class);
        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        for (AppUserPO userPO : users) {
            if (!Boolean.TRUE.equals(userPO.getCheckedMobile()) || StringUtils.isBlank(userPO.getMobile())) {
                updateMobileFun(userPO.getId(), mobile, date, WechatThirdUserPO.class);
            }
        }

    }

    private void updateWechatThirdMobile(String userId, String mobile, Date date) {
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId));
        List<WechatThirdUserPO> users = mongoTemplate.find(query, WechatThirdUserPO.class);
        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        for (WechatThirdUserPO userPO : users) {
            if (!Boolean.TRUE.equals(userPO.getCheckedMobile()) || StringUtils.isBlank(userPO.getMobile())) {
                updateMobileFun(userPO.getId(), mobile, date, WechatThirdUserPO.class);
            }
        }

    }

    private void updateMobileFun(String id, String mobile, Date date, Class clazz) {
        Query queryUpdate = new Query().addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.set("mobile", mobile);
        update.set("checkedMobile", true);
        update.set("checkedMobileTime", date);
        update.set("updatedTime", date);
        mongoTemplate.updateFirst(queryUpdate, update, clazz);
    }
}
